package com.neusoft.hifly.lock;

import java.util.concurrent.TimeUnit;

import org.redisson.Redisson;
import org.redisson.api.RLock;

import com.neusoft.hifly.lock.utils.Log;

/**
 * 针对源码Redisson进行一层封装
 */
public class RedissonLock {

	private RedissonManager redissonManager;
	private Redisson redisson;

	public RedissonLock(final RedissonManager redissonManager) {
		this.redissonManager = redissonManager;
		this.redisson = redissonManager.getRedisson();
	}

	public RedissonLock() {
	}

	/**
	 * 加锁操作 （设置锁的有效时间）
	 *
	 * @param lockName
	 *            锁名称
	 * @param leaseTime
	 *            锁有效时间
	 */
	public void lock(final String lockName, final long leaseTime) {
		final RLock rLock = redisson.getLock(lockName);
		rLock.lock(leaseTime, TimeUnit.SECONDS);
	}

	/**
	 * 加锁操作 (锁有效时间采用默认时间30秒）
	 *
	 * @param lockName
	 *            锁名称
	 */
	public void lock(final String lockName) {
		final RLock rLock = redisson.getLock(lockName);
		rLock.lock();
	}

	/**
	 * 加锁操作(tryLock锁，没有等待时间）
	 *
	 * @param lockName
	 *            锁名称
	 * @param leaseTime
	 *            锁有效时间
	 */
	public boolean tryLock(final String lockName, final long leaseTime) {

		final RLock rLock = redisson.getLock(lockName);
		boolean getLock = false;
		try {
			getLock = rLock.tryLock(leaseTime, TimeUnit.SECONDS);
		} catch (final InterruptedException e) {
			Log.error("获取Redisson分布式锁[异常]，lockName=" + lockName, e);
			e.printStackTrace();
			return false;
		}
		return getLock;
	}

	/**
	 * 加锁操作(tryLock锁，有等待时间）
	 *
	 * @param lockName
	 *            锁名称
	 * @param leaseTime
	 *            锁有效时间
	 * @param waitTime
	 *            等待时间
	 */
	public boolean tryLock(final String lockName, final long leaseTime, final long waitTime) {

		final RLock rLock = redisson.getLock(lockName);
		boolean getLock = false;
		try {
			getLock = rLock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
		} catch (final InterruptedException e) {
			Log.error("获取Redisson分布式锁[异常]，lockName=" + lockName, e);
			e.printStackTrace();
			return false;
		}
		return getLock;
	}

	/**
	 * 解锁
	 *
	 * @param lockName
	 *            锁名称
	 */
	public void unlock(final String lockName) {
		redisson.getLock(lockName).unlock();
	}

	/**
	 * 判断该锁是否已经被线程持有
	 *
	 * @param lockName
	 *            锁名称
	 */
	public boolean isLock(final String lockName) {
		final RLock rLock = redisson.getLock(lockName);
		return rLock.isLocked();
	}

	/**
	 * 判断该线程是否持有当前锁
	 *
	 * @param lockName
	 *            锁名称
	 */
	public boolean isHeldByCurrentThread(final String lockName) {
		final RLock rLock = redisson.getLock(lockName);
		return rLock.isHeldByCurrentThread();
	}

	public RedissonManager getRedissonManager() {
		return redissonManager;
	}

	public void setRedissonManager(final RedissonManager redissonManager) {
		this.redissonManager = redissonManager;
	}
}
